# -*- coding: utf-8 -*-

"""
@author: Laowang
@contact: QQ:1125564921
@Created on: 2022/6/21
@Remark: 
"""

from typing import List
from collections import defaultdict

from .xt4_future_api_cfg import XT4FutureConfig
from .xt4_future_utils import auth_require_, public_request_

from framework_strategy.gopy.base import GateWay
from framework_strategy.gopy.gateways.utils import (
    RequestParamterObj,
    auth_require,
    public_request,
    ResponseKlineObj,
    ResponseTickerObj,
    ResponseOrderBookObj,
    ResponseTradesObj,
    ResponseBalanceObj,
    ResponseOrderObj,
    ResponseOrdersObj,
    ResponseCancelOrderObj,
    ResponseAccountOrderObj,
    ResponseMineOrdersObj
)
from framework_strategy.gopy.base.constant import *


def market_config_response(data, parameter=None):
    """ account response """
    # print("[account_response] ", data).
    if not data.get("result"):
        return data
    return data["result"]


@public_request(key=public_request_, response_handle=market_config_response)
def get_all_market_config(self, event) -> RequestParamterObj:
    """ Access all market config """
    # print("--get_all_market_config--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_MARKET_CONFIG, event)

def kline_response(data, parameter=None):
    """ kline response """
    # TODO symbol必传
    if not data.get("result"):
        return data

    ndata = defaultdict(list)
    for d in data["result"]:
        ndata["data"].append(
            ResponseKlineObj(
                d["t"],
                d["o"],
                d["h"],
                d["l"],
                d["c"],
                d["v"],
            )
        )
    return ndata


@public_request(key=public_request_, response_handle=kline_response)
def get_klines(self, event) -> RequestParamterObj:
    """ Get Klines """
    # print("--get_klines--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_KLINE, event)


def ticker_response(data, parameter=None):
    """ ticker response """
    # TODO 缺少档口委托量
    if not data.get("result"):
        return data

    ndata = dict()
    ndata["data"] = ResponseTickerObj(
        data["result"]["bp"],
        None,
        data["result"]["ap"],
        None,
        data["result"]["c"],
    )
    return ndata


@public_request(key=public_request_, response_handle=ticker_response)
def get_ticker(self, event) -> RequestParamterObj:
    """ Aggregate market """
    # print("--get_ticker--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_TICKER, event)


def tickers_response(data, parameter=None):
    """ tickers response """
    # TODO 缺少档口委托量

    if not data.get("result"):
        return data

    ndata = list()
    for v in data["result"]:
        ndata.append(ResponseTickerObj(
        v["bp"],
        None,
        v["ap"],
        None,
        v["c"],
        v["s"]
        ))
    return {"data": ndata}


@public_request(key=public_request_, response_handle=tickers_response)
def get_tickers(self, event) -> RequestParamterObj:
    """ All aggregate market """
    # print("--get_tickers--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_TICKERS, event)

def depth_response(data, parameter=None):
    """ depth response """
    if not data.get("result"):
        return data
    ndata = dict()
    ndata["data"] = ResponseOrderBookObj(data["result"]["a"], data["result"]["b"])
    return ndata


@public_request(key=public_request_, response_handle=depth_response)
def get_depth(self, event) -> RequestParamterObj:
    """ Gain market depth """
    # print("--get_depth--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_DEPTH, event)

def trades_response(data, parameter=None):
    """ trades response """
    # TODO 没有成交量ID a:成交张数
    if not data.get("result"):
        return data
    ndata = defaultdict(list)
    for d in data["result"]:
        ndata["data"].append(ResponseTradesObj(
            None,
            d["p"],
            d["a"],
            d["m"],
            d["t"],
        ))
    return ndata

@auth_require(key=public_request_, response_handle=trades_response)
def get_trades(self, event) -> RequestParamterObj:
    """ Get trade history """
    # print("--get_trades--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_TRADES, event)

def balance_response(data, parameter=None):
    """ balance response """

    if not data.get("result"):
        return data
    ndata = defaultdict(list)
    for asset in data["result"]:
        ndata["data"].append(
            ResponseBalanceObj(
                asset["coin"],
                asset["availableBalance"],
                asset["openOrderMarginFrozen"]
            )
        )
    return ndata

@auth_require(key=auth_require_, response_handle=balance_response)
def get_balance(self, event) -> RequestParamterObj:
    """ Get account balance """
    # 获取资产每秒3次，其他方法单个用户每秒10次，单个IP每分钟1000次，超出锁定账户10分钟。
    # unix时间戳(毫秒)
    # print("--get_balance--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_BALANCE, event)

def fund_response(data, parameter=None):
    """ fund response """
    if not data.get("result"):
        return data

    ndata = defaultdict(list)
    for k, v in data["result"].items():
        ndata["data"].append(
            ResponseBalanceObj(
                k,
                v["available"],
                v["freeze"]
            )
        )
    return ndata

@auth_require(key=auth_require_, response_handle=fund_response)
def get_fund(self, event) -> RequestParamterObj:
    """ Gets the corresponding information for an account """
    # print("--get_fund--", self, event)
    return RequestParamterObj("GET", XT4FutureConfig.GET_FUNDS, event)

def send_order_response(data, parameter=None):
    """ order response """
    if not data.get("result"):
        return data
    ndata = dict()
    ndata["data"] = ResponseOrderObj(
        data["data"].get("id") or 0,
        parameter.data.event_data.market,
        parameter.data.event_data.type,
        parameter.data.event_data.price,
        parameter.data.event_data.number
    )
    return ndata


@auth_require(key=auth_require_, response_handle=send_order_response)
def send_order(self, event) -> RequestParamterObj:
    """ Order """
    # print("--send_order--", self, event)
    return RequestParamterObj("POST", XT4FutureConfig.SEND_ORDER, event)

class XT4FutureGateway(GateWay):

    exchanges = ["XT4Future"]

    def __init__(self, main_engine, event_engine, gateway_name="XT4Future", proxy=None) -> None:
        super().__init__(main_engine, event_engine, gateway_name, proxy)

    ON_EVENT: List = [
        # (XT4_EVENT_SERVERTIMES, get_server_time),
        # (XT4_EVENT_ACCOUNT, get_account),
        (XT4FUTURE_EVENT_MARKETCONFIG, get_all_market_config),
        (XT4FUTURE_EVENT_KLINE, get_klines),
        (XT4FUTURE_EVENT_TICKER, get_ticker),
        (XT4FUTURE_EVENT_TICKERS, get_tickers),
        (XT4FUTURE_EVENT_MARKETDEPTH, get_depth),
        (XT4FUTURE_EVENT_ORDER_TRADE, get_trades),
        (XT4FUTURE_EVENT_ACCOUNT_BALANCE, get_balance),
        (XT4FUTURE_EVENT_ACCOUNT_FUND, get_fund),
        (XT4FUTURE_EVENT_SENDORDER, send_order),
        # (XT4_EVENT_SENDORDERS, send_orders),
        # (XT4_EVENT_CANCELORDER, cancel_order),
        # (XT4_EVENT_CANCELORDERS, cancel_orders),
        # (XT4_EVENT_ORDER_STATUS, get_order),
        # (XT4_EVENT_OPENORDER, get_open_order),
        # (XT4_EVENT_ORDERS_STATUS, get_orders),
        # (XT4_EVENT_ACCOUNT_MINE_TRADES, get_mine_trades),
    ]
